package com.easyctba.core.algorithm.exec;

import com.easyctba.core.domain.CtbaFiasClass;
import com.easyctba.core.enums.PythonConfig;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class FiasExec {
    /**
     * fias表生成
     * @param list 分析序列
     * @param interval 分析间隔
     * @param id 分析全局唯一id
     * @return fias表在oss的路径
     */
    public String fiasTable(List<String> list, Long interval, Long id){
        String pythonPath = PythonConfig.basePath+"fias/fias_table.py";
        // 参数1：数据列表 参数2采样间隔 参数3：fias分析id用作文件名
        String[] args1 = new String[]{PythonConfig.localPython, pythonPath, list.toString(), String.valueOf(interval), String.valueOf(id)};
        try {
            // 执行Python文件，并传入参数
            Process process = Runtime.getRuntime().exec(args1);
            // 获取Python输出字符串作为输入流被Java读取
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String actionStr = in.readLine();
            if (actionStr != null) {
                System.out.println(actionStr);
            }
            in.close();
            int i = process.waitFor();
            System.out.println(i);
            return actionStr;
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成矩阵表
     * @param list 分析序列
     * @param id fias id
     * @param matrix 初始化的矩阵表
     * @return 矩阵表本地路径
     */
    public String matrixTable(List<String> list, Long id,List<List<Object>> matrix){
        //第一行的值，第一列的值应该和这个相同
        List<Object> firstRow = matrix.get(0);
        //格式化
        List<String> regex = firstRow.stream().map(i -> i.toString().split(" - ")[0]).toList();
        //序对
        List<List<String>> pair = this.pair(list);
        for (List<String> item : pair) {
            String column = item.get(0);//列
            String row = item.get(1);//行
            int i = regex.indexOf(column);
            int j = regex.indexOf(row);
            Integer num = (Integer) matrix.get(i).get(j);
            num++;
            matrix.get(i).set(j,num);
        }
        System.out.println(matrix);
        return this.fiasMatrix(matrix, id);
    }

    /**
     * 生成序对
     * @param list 原始数组
     * @return 序对数组
     */
    private List<List<String>> pair(List<String> list){
        List<List<String>> output = new ArrayList<>();
        for (int i = 0; i < list.size() - 1; i++) {
            List<String> pair = new ArrayList<>();
            pair.add(list.get(i));
            pair.add(list.get(i+1));
            output.add(pair);
        }
        return output;
    }

    /**
     * 初始化矩阵
     * @param classList 编码规则
     * @return 初始矩阵
     * 0 编码1NUM 0 0 0
     * 编码1NUM
     * 0
     * 0
     * 0
     */
    public List<List<Object>> initMatrix(List<CtbaFiasClass> classList){
        List<List<Object>> output = new ArrayList<>();
        int size = classList.size();
        //表头
        List<Object> title = new ArrayList<>();
        title.add("分类编号");
        for (CtbaFiasClass ctbaFiasClass : classList) {
            title.add(ctbaFiasClass.getClassNum()+" - "+ctbaFiasClass.getClassName());
        }
        output.add(title);
        for (int i = 0; i < size; i++) {
            //行
            ArrayList<Object> objects = new ArrayList<>();
            objects.add(classList.get(i).getClassNum()+" - "+classList.get(i).getClassName());
            for (int j = 0; j < size; j++) {
                objects.add(0);
            }
            output.add(objects);
        }
        return output;
    }

    /**
     * fias矩阵表生成
     * @param matrix 矩阵序列
     * @param id 分析全局唯一id
     * @return fias矩阵表在oss的路径
     */
    private String fiasMatrix(List<List<Object>> matrix, Long id){
        String pythonPath = PythonConfig.basePath+"fias/fias_matrix.py";
        // 参数1：数据列表 参数2：fias分析id用作文件名
        String[] args1 = new String[]{PythonConfig.localPython, pythonPath, matrix.toString(), String.valueOf(id)};
        try {
            // 执行Python文件，并传入参数
            Process process = Runtime.getRuntime().exec(args1);
            // 获取Python输出字符串作为输入流被Java读取
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
            String actionStr = in.readLine();
            if (actionStr != null) {
                System.out.println(actionStr);
            }
            in.close();
            int i = process.waitFor();
            System.out.println(i);
            return actionStr;
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成雷达图信息
     * @param codeList 编码列表
     * @param classList 分类列表
     * @return value:结果列表List<String> max:最大值String
     */
    public Map<String,Object> genRadar(List<String> codeList, List<CtbaFiasClass> classList) {
        //创建map<编码编号，编码频数>
        Map<String, Integer> map = new LinkedHashMap<>();
        //初始化map
        for (CtbaFiasClass ctbaFiasClass : classList) {
            String classNum = ctbaFiasClass.getClassNum();
            map.put(classNum,0);
        }
        //给map赋值
        for (String s : codeList) {
            map.put(s, map.getOrDefault(s, 0) + 1);
        }
        int size = codeList.size();
        BigDecimal max=new BigDecimal(0);
        List<String> res = new ArrayList<>();
        //将赋值的频数转换成占比
        for (Integer value : map.values()) {
            BigDecimal dividend = new BigDecimal(value);
            BigDecimal divisor = new BigDecimal(size);
            //四舍五入，保留3位小数
            BigDecimal divide = dividend.divide(divisor, 3, RoundingMode.HALF_UP);
            //求最大值
            if (divide.compareTo(max)>0 ){
                max=divide;
            }
            res.add(divide.toString());
        }
        Map<String, Object> result = new HashMap<>();
        result.put("value",res);
        result.put("max",max.toString());
        return result;
    }

    /**
     * 获取大类占比
     * @param value 小类占比
     * @param size 每个大类的大小
     * @param names 大类名
     * @return title：大类名 value：数值
     */
    public List<Map<String, Object>> getCategoryRate(List<String> value, List<Long> size, List<String> names) {
        List<List<String>> result = new ArrayList<>();
        int currentCount = 0;
        List<String> currentSublist = new ArrayList<>();

        for (String s : value) {
            currentSublist.add(s);

            if (currentCount < size.size()) {
                // 检查是否达到了当前指定的分割长度
                if (currentSublist.size() == size.get(currentCount)) {
                    result.add(currentSublist);
                    currentSublist = new ArrayList<>(); // 重置当前子列表
                    currentCount++; // 移动到下一个分割长度
                }
            } else {
                // 如果list2中的元素已经用完，剩下的list1元素都加入当前子列表
                break;
            }
        }
        List<Map<String, Object>> maps = new ArrayList<>();
        int i=0;// 计数器
        //遍历result，分别计算对应的比率
        for (List<String> strings : result) {
            BigDecimal res = new BigDecimal(0);
            for (String s : strings) {
                //值信息
                BigDecimal bigDecimal = new BigDecimal(s);
                res = res.add(bigDecimal);
            }
            HashMap<String, Object> map = new HashMap<>();
            double v = Double.parseDouble(res.toString());
            map.put("value",v);
            map.put("title",names.get(i));
            i++;
            maps.add(map);
        }
        return maps;
    }
}
